package app.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import app.model.Application;
import app.model.Member;

/** 
 * 
 * @author Nachman Mathieu
 * @author David Gianorio
 * @author Faton Alia
 * 
 * This class contains all queries needed to get Application Objects */

@Repository
@Transactional
public class MemberDao {

	@PersistenceContext
	private EntityManager em;
	
	/** This method will return the list of all members, it will throw a NoResultException if the list is empty */
	public synchronized List<Member> getAllMembers() {

		@SuppressWarnings("unchecked")
		List<Member> listOfMembers = (List<Member>)em.createQuery("SELECT m FROM Member m").getResultList();

		if(listOfMembers.isEmpty()){
			throw new NoResultException("The list of members is empty");
		} else {
			return listOfMembers;
		}
	}
	
	/** This method will return the list of the Top developpers, it will throw a NoResultException if the list is empty */
	public synchronized List<Member> getTopDevelopers(){
		
		List<Member> listOfTopDev = (List<Member>)em.createQuery("SELECT m FROM Member m ORDER BY m.countNumberOfUploads DESC").setMaxResults(10).getResultList();
		
		if(listOfTopDev.isEmpty()){
			throw new NoResultException("The list of developers is empty");
		} else {
			return listOfTopDev;
		}
	}
	
	public synchronized Member getMemberByUsernameAndPassword(String username, String password){
		
		List<Member> memberResultList = (List<Member>)em.createQuery("SELECT m FROM Member m WHERE m.username=:username AND m.password=:password")
		.setParameter("username", username).setParameter("password", password).setMaxResults(1).getResultList();
		
		if(memberResultList.isEmpty()){
			throw new NoResultException("No user found this this username/password");
		} else {
			
			Member membReturned = new Member();
			
			for(Member membResult : memberResultList){
				membReturned = membResult;
			}
			
			return membReturned;
		}
	}
	
	public synchronized Object find(Long id){
		return em.find(Member.class, id);
	}

	public synchronized Object merge(Object obj){
		return em.merge(obj);
	}

	public synchronized void persist(Object obj){
		em.persist(obj);
	}
}